package com.zhangx.study.demo.run;

import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import org.springframework.web.WebApplicationInitializer;
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext;
import org.springframework.web.servlet.DispatcherServlet;

import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletRegistration;

/**
 * @ClassName SpringMain
 * @Description spring run方法背后发生了什么
 * @Author zhangx
 * @Date 2020/11/12 8:22
 **/
public class SpringMain implements WebApplicationInitializer {

    /**
     * servlet 3.1必然会调用实现WebApplicationInitializer接口的onStartup方法
     * 在这里进行配置
     * @param servletContext
     * @throws ServletException
     */
    @Override
    public void onStartup(ServletContext servletContext) throws ServletException {
        //        用xml时候都是这样
//        new ClassPathXmlApplicationContext("xx.xml");

//        去xml,注意web工程用了这个WebApplicationContext
        AnnotationConfigWebApplicationContext ac = new AnnotationConfigWebApplicationContext();
        ac.register(AppConfig.class);
//        不加这样一行，注册json解析器会报错缺少java.lang.IllegalStateException: No ServletContext set
        ac.setServletContext(servletContext);
//        官方代码中要refresh，这里面涉及到东西很多
        ac.refresh();//手动启动spring容器
//        上面相当于解析applicationContext.xml
//        ----------------web上半部分--------------

//        ----------------web下半部分--------------
//        等价于web.xml配置
//        实例化servlet
        DispatcherServlet servlet = new DispatcherServlet();
        servlet.setApplicationContext(ac);
//        注册到tomcat
        ServletRegistration.Dynamic registration = servletContext.addServlet("spring",servlet);
        registration.setLoadOnStartup(1);
        registration.addMapping("/*");
    }

    public static void run() throws LifecycleException {
        Tomcat tomcat = new Tomcat();
        Connector connector = new Connector();
        connector.setPort(8088);
        connector.setURIEncoding("UTF-8");
        tomcat.getService().addConnector(connector);

//        docbase不能瞎写 启动不起来
//        不声明为webappp，是不会回调onStartup方法的
        tomcat.addWebapp("/project","E:\\tmp\\");

        tomcat.start();
        tomcat.getServer().await();
    }

    public static void main(String[] args) {
        try {
            SpringMain.run();
        } catch (LifecycleException e) {
            e.printStackTrace();
        }
    }
}
